package com.drug.wms.service.impl;

import com.drug.common.core.domain.model.LoginUser;
import com.drug.common.enums.BusinessWarehouseTypeEnum;
import com.drug.common.exception.ServiceException;
import com.drug.common.utils.DateUtils;
import com.drug.common.utils.SecurityUtils;
import com.drug.common.utils.uuid.IdUtils;
import com.drug.wms.domain.BusGoodsBaseInfo;
import com.drug.wms.domain.BusSkuStock;
import com.drug.wms.domain.BusSkuStockDetailsResponseVO;
import com.drug.wms.domain.BusWarehoseInfo;
import com.drug.wms.mapper.BusGoodsBaseInfoMapper;
import com.drug.wms.mapper.BusSkuStockMapper;
import com.drug.wms.service.IBusSkuStockService;
import com.drug.wms.service.IBusWarehoseInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 库存Service业务层处理
 *
 * @author ruoyi
 * @date 2021-12-05
 */
@Service
public class BusSkuStockServiceImpl implements IBusSkuStockService {

    @Autowired
    private BusSkuStockMapper busSkuStockMapper;
    @Autowired
    private IBusWarehoseInfoService iBusWarehoseInfoService;
    @Autowired
    private BusGoodsBaseInfoMapper busGoodsBaseInfoMapper;

    /**
     * 查询库存
     *
     * @param id 库存主键
     * @return 库存
     */
    @Override
    public BusSkuStock selectBusSkuStockById(String id) {
        return busSkuStockMapper.selectBusSkuStockById(id);
    }

    @Override
    public BusSkuStockDetailsResponseVO selectBusSkuStockDetailsById(String id) {
        return busSkuStockMapper.selectBusSkuStockDetailsById(id);
    }

    /**
     * 查询库存列表
     *
     * @param busSkuStock 库存
     * @return 库存
     */
    @Override
    public List<BusSkuStock> selectBusSkuStockList(BusSkuStock busSkuStock) {
        return busSkuStockMapper.selectBusSkuStockList(busSkuStock);
    }

    /**
     * 新增库存
     *
     * @param busSkuStockList 库存 扣库存传负数
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertOrUpdateSkuStock(List<BusSkuStock> busSkuStockList) {
        AtomicInteger result = new AtomicInteger();
        busSkuStockList.forEach(busSkuStock -> {
            BusSkuStock queryParam = new BusSkuStock();
            queryParam.setWarehouseNo(busSkuStock.getWarehouseNo());
            queryParam.setBatchNo(busSkuStock.getBatchNo());
            queryParam.setSkuId(busSkuStock.getSkuId());
            List<BusSkuStock> busSkuStocks = busSkuStockMapper.selectBusSkuStockList(queryParam);
            if (busSkuStocks.size() > 0) {
                BusSkuStock updateSkuStock = busSkuStocks.get(0);
                BigDecimal canSaleAmount = updateSkuStock.getCanSaleAmount().add(busSkuStock.getCanSaleAmount());
                updateSkuStock.setCanSaleAmount(canSaleAmount);
                BigDecimal amount = updateSkuStock.getAmount().add(busSkuStock.getAmount());
                updateSkuStock.setAmount(amount);
                if(busSkuStock.getCartonSize()!=null && busSkuStock.getAverageCostPrice()!=null){
                    BigDecimal inventoryAmount = amount.multiply(new BigDecimal(busSkuStock.getCartonSize() + ""))
                            .multiply(busSkuStock.getAverageCostPrice());
                    updateSkuStock.setInventoryAmount(inventoryAmount);
                }
                result.set(busSkuStockMapper.updateBusSkuStock(updateSkuStock));
            } else {
                busSkuStock.setUpdateTime(DateUtils.getNowDate());
                BigDecimal amount = busSkuStock.getAmount();
                if(busSkuStock.getCartonSize()!=null && busSkuStock.getAverageCostPrice()!=null){
                    BigDecimal inventoryAmount = amount.multiply(new BigDecimal(busSkuStock.getCartonSize() + ""))
                            .multiply(busSkuStock.getAverageCostPrice());
                    busSkuStock.setInventoryAmount(inventoryAmount);
                }
                result.set(busSkuStockMapper.insertBusSkuStock(busSkuStock));
            }
        });
        return result.get();
    }

    /**
     * 修改库存
     *
     * @param busSkuStock 库存
     * @return 结果
     */
    @Override
    public int updateBusSkuStock(BusSkuStock busSkuStock) {
        busSkuStock.setUpdateTime(DateUtils.getNowDate());
        return busSkuStockMapper.updateBusSkuStock(busSkuStock);
    }

    /**
     * 批量删除库存
     *
     * @param ids 需要删除的库存主键
     * @return 结果
     */
    @Override
    public int deleteBusSkuStockByIds(String[] ids) {
        return busSkuStockMapper.deleteBusSkuStockByIds(ids);
    }

    /**
     * 删除库存信息
     *
     * @param id 库存主键
     * @return 结果
     */
    @Override
    public int deleteBusSkuStockById(String id) {
        return busSkuStockMapper.deleteBusSkuStockById(id);
    }

    @Override
    public BusSkuStock selectBusSkuStockBySkuId(String skuId, Long deptId) {
        if (deptId == null) {
            deptId = getLoginUser().getDeptId();
        }
        return busSkuStockMapper.selectBusSkuStockBySkuId(skuId, deptId);
    }


    private LoginUser getLoginUser() {
        LoginUser sysUser = null;
        try {
            sysUser = SecurityUtils.getLoginUser() != null ? (LoginUser) SecurityUtils.getLoginUser() : null;
        } catch (Exception e) {
            //e.printStackTrace();
            sysUser = null;
        }
        return sysUser;
    }

    /**
     * 变更基本单位（零整库移库操作）
     */
    @Override
    @Transactional
    public int changeBaseUnit(String id, String wareHoseId, Integer moveNum) {
        // 查询库存表基本信息
        BusSkuStock busSkuStock = busSkuStockMapper.selectBusSkuStockById(id);
        // 查询所选择仓库基本信息
        BusWarehoseInfo warehoseInfo = iBusWarehoseInfoService.selectBusWarehoseInfoById(wareHoseId);
        // 判断当前库存所属仓库是否为整活库，需要变更仓库是否为零活库
            if (warehoseInfo == null || !BusinessWarehouseTypeEnum.SCATTERED_WAREHOUSE.getCode().equals(warehoseInfo.getWarehouseTypeCode())) {
            throw new ServiceException("需要移动的仓库不存在或不为零货库！");
        }
        // 计算变更后剩余库存数量
        int i = busSkuStock.getAmount().intValue() - moveNum;
        if (i < 0) {
            throw new ServiceException("库存数量小于需要移动的数量！");
        }
        // 成本均价
        BigDecimal costPrice = busSkuStock.getAverageCostPrice();
        // 如果库存为0则删除当前库存记录
        if (i == 0) {
            busSkuStockMapper.deleteBusSkuStockById(id);
        } else {
            // 更新库存
            BigDecimal difference = busSkuStock.getAmount().subtract(BigDecimal.valueOf(moveNum));
            busSkuStock.setAmount(difference);
            // 更新库存金额
            BigDecimal divide = busSkuStock.getInventoryAmount().subtract(costPrice.multiply(BigDecimal.valueOf(moveNum)));
            busSkuStock.setInventoryAmount(divide);
            busSkuStockMapper.updateBusSkuStock(busSkuStock);
        }
        // 查询当前商品在需要变更仓库内是否存在相同批号与商品编号的记录
        BusSkuStock query = new BusSkuStock();
        query.setWarehouseNo(warehoseInfo.getWarehouseNo());
        query.setBatchNo(busSkuStock.getBatchNo());
        query.setSkuId(busSkuStock.getSkuId());
        List<BusSkuStock> skuStocks = busSkuStockMapper.selectBusSkuStockList(query);
        // 查询商品基本信息
        BusGoodsBaseInfo baseInfo = busGoodsBaseInfoMapper.selectBusGoodsBaseInfoByGoodsNo(busSkuStock.getSkuId());
        // 装箱规格
        Long cartonSize = baseInfo.getCartonSize();
        // 若不存在则新增，若存在则更新
        BigDecimal amount = new BigDecimal(moveNum * cartonSize);
        if (CollectionUtils.isEmpty(skuStocks)) {
            // 获取基本信息
            BusSkuStock newStock = new BusSkuStock();
            BeanUtils.copyProperties(busSkuStock, newStock);
            newStock.setId(IdUtils.fastSimpleUUID());
            newStock.setUnit(baseInfo.getBasicUnitNo());
            newStock.setBaseUnit(baseInfo.getBasicUnitNo());
            newStock.setAmount(amount);
            newStock.setInventoryAmount(new BigDecimal(moveNum).multiply(costPrice));
            newStock.setConvertRate(cartonSize.intValue());
            newStock.setWarehouseNo(warehoseInfo.getWarehouseNo());
            newStock.setWarehouseTypeCode(warehoseInfo.getWarehouseTypeCode());
            return busSkuStockMapper.insertBusSkuStock(newStock);
        } else {
            BusSkuStock newStock = skuStocks.get(0);
            newStock.setAmount(newStock.getAmount().add(amount));
            newStock.setInventoryAmount(newStock.getInventoryAmount().add(new BigDecimal(moveNum).multiply(costPrice)));
            newStock.setWarehouseNo(warehoseInfo.getWarehouseNo());
            return busSkuStockMapper.updateBusSkuStock(newStock);
        }
    }
}
